#!/usr/bin/env python

import cgi
import os
import sys
import urllib
from datetime import datetime
import logging

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

ADMIN_EMAIL = ['g77ccer@gmail.com','akirika@gmail.com']
CONTENT_TYPE = 'text/html; charset=utf-8'

from qlog.BlogDao import BlogDao
blogDao = BlogDao()

def str2datetime(s):
    parts = s.split('.')
    dt = datetime.strptime(parts[0], "%Y-%m-%d %H:%M:%S")
    return dt.replace(microsecond=int(parts[1]))


class BasePage(webapp.RequestHandler):

    def output(self, tpl, vars):
        """ 
        output with template and variables 
        """
        self.response.headers['Content-Type'] = CONTENT_TYPE
        path = os.path.join(os.path.dirname(__file__), 'tpl/%s.html' % tpl)
        self.response.out.write(template.render(path, vars))

    def gotopage(self, params = []):
        url = self.request.path
        if params != [] :
            url = url + "?" + urllib.urlencode(params)

        self.redirect(users.create_login_url(self.request.uri))
        return None
        

    def getLoggedInUser(self):
        """ 
        get current session user 
        """
        return users.get_current_user()

    def requireLogin(self):
        """
        requrie login,
        return user or redirect to login page
        """
        user = self.getLoggedInUser()
        if user:
            return user
        else:
            self.redirect(users.create_login_url(self.request.uri))
            return None

    def requireAdmin(self):
        """
        requrie login,
        return user or redirect to login page
        """
        user = self.requireLogin()
        if(user and user.email() in ADMIN_EMAIL):
            return user
        else:
            self.redirect(users.create_login_url(self.request.uri))
            return None

    def getQuery(self):
        qs = cgi.parse_qs(self.request.query_string)
        args = {}
        for k in qs:
            args[k] = qs[k][0]
        return args
    

class BlogListPage(BasePage):
        
    def get(self):

        vars = {}
        vars['current_page'] = 'blog'

        user = users.get_current_user()
        if user:
            vars['guest'] = {
                'email':user.email(), 
                'nickname':user.nickname()
            }
        else:
            vars['guest'] = None



        upto_datetime = None
        prev_datetime_ns = ''
        next_datetime_ns = ''

        itemPerPage = 5

        try:
            """ current upto date """
            upto_datetime_s = self.request.get('upto_datetime', default_value='')
            if upto_datetime_s != '':
                upto_datetime = str2datetime(upto_datetime_s)
        except ValueError:
            upto_datetime = None

        category_name = self.request.get('category_name')

        blogList = blogDao.getList(upto_datetime = upto_datetime, category_name=category_name, show_hide=False, itemPerPage=itemPerPage)
        vars['blogList'] = blogList[:itemPerPage]
        if len(blogList) == itemPerPage + 1 :
            """ have next """
            next_datetime_ns = str(blogList[-1].create_date)

        if blogList and len(blogList) >= 1:
            prev_blog = blogDao.getPrev(blogList[0], limit = itemPerPage)
            logging.info(prev_blog)
            if prev_blog and len(prev_blog) >= 1 :
                prev_datetime_ns = str(prev_blog[0].create_date)
        
        vars['categoryList'] = blogDao.getCategoryList()

        vars['categoryName'] = category_name
        vars['prev_datetime'] = prev_datetime_ns
        vars['next_datetime'] = next_datetime_ns

        self.output('list', vars)


class BlogEntryPage(BasePage):
    def get(self):
        vars = {}
        vars['current_page'] = 'blog'
        
        user = self.getLoggedInUser()
        if user:
            vars['guest'] = {'email':user.email(),'nickname':user.nickname()}
        else:
            vars['guest'] = None

        key = self.request.get('key')
        vars['blog'] = blogDao.get(key)
        vars['categoryList'] = blogDao.getCategoryList()

        self.output('entry', vars)


class BlogAdminPage(BasePage):

    def post(self):
        return self.get()

    def get(self):
        admin = self.requireAdmin()
        if admin == None:
            return

        action = self.request.get('action')
        vars = {'tpl':'', 'stat':'None', 'next_action':'', 'action':action}

        tpl = ''
        stat = ''
        next_action = ''


        """
        category operation
        """
        if action == 'addCategory':
            name = self.request.get('name')
            if name == '':
                stat = 'Empty Value'
            else:
                stat = blogDao.addCategory(name)
            next_action = "listCategory"
            tpl = "admin_optstat"

        elif action == 'setCategory':
            key = self.request.get('key')
            name = self.request.get('name')
            if name == '' or key == '':
                stat = 'Empty Value'
            else:
                stat = blogDao.setCategory(key, name)
            next_action = "listCategory"
            tpl = "admin_optstat"

        elif action == 'deleteCategory':
            key = self.request.get('key')
            if key == '':
                stat = 'Empty Value'
            else:
                stat = blogDao.deleteCategory(key)
            next_action = "listCategory"
            tpl = "admin_optstat"

        elif action == 'listCategory':
            vars['categoryList'] = blogDao.getCategoryList()
            tpl = "admin_list_category"


        
            """
            blog operation
            """

        elif action == 'listBlog':

            upto_datetime = None
            prev_datetime_ns = ''
            next_datetime_ns = ''

            itemPerPage = 5

            try:
                """ current upto date """
                upto_datetime_s = self.request.get('upto_datetime', default_value='')
                if upto_datetime_s != '':
                    upto_datetime = str2datetime(upto_datetime_s)
            except ValueError:
                upto_datetime = None

            category_name = self.request.get('category_name')

            blogList = blogDao.getList(upto_datetime = upto_datetime, category_name=category_name, show_hide=True, itemPerPage=itemPerPage)
            vars['blogList'] = blogList[:itemPerPage]
            if len(blogList) == itemPerPage + 1 :
                """ have next """
                next_datetime_ns = str(blogList[-1].create_date)

            if blogList and len(blogList) >= 1:
                prev_blog = blogDao.getPrev(blogList[0], limit = itemPerPage)
                logging.info(prev_blog)
                if prev_blog and len(prev_blog) >= 1 :
                    prev_datetime_ns = str(prev_blog[0].create_date)
            
            vars['categoryList'] = blogDao.getCategoryList()

            vars['categoryName'] = category_name
            vars['prev_datetime'] = prev_datetime_ns
            vars['next_datetime'] = next_datetime_ns

            tpl = "admin_list_blog"

        elif action == 'composeBlog':
            
            key     = self.request.get('key')
            if(key):
                """ edit """
                vars['blog'] = blogDao.get(key)

            vars['categoryList'] = blogDao.getCategoryList()
            tpl = "admin_compose"

        elif action == 'postBlog':
            
            key     = self.request.get('key')

            title   = self.request.get('title')
            content = self.request.get('content')
            category = self.request.get('category')
            tags    = self.request.get('tags')

            if(key == ''):
                """ new """
                stat = blogDao.add(title, content, category, tags)
            else:
                """ edit """
                stat = blogDao.set(key, title, content, category, tags)

            next_action = "listBlog"
            tpl = "admin_optstat"
       
        elif action == 'setDisplay':
            key     = self.request.get('key')
            display = self.request.get('display', 'true')

            stat = blogDao.setDisplay(key, (display == 'true'))

            next_action = "listBlog"
            tpl = "admin_optstat"


        elif action == 'deleteBlog':
            key     = self.request.get('key')

            stat = blogDao.delete(key)
            next_action = "listBlog"
            tpl = "admin_optstat"

        elif action == '':
            tpl = "admin_home"
            
        else:
            tpl = "admin_notfound"

        vars['stat'] = stat
        vars['auto_redirect'] = ( stat == True and tpl == 'admin_optstat' )
        
        query = self.getQuery()
        query['action'] = next_action

        vars['next_url'] = self.request.path + '?' + urllib.urlencode(query)

        self.output(tpl, vars)


application = webapp.WSGIApplication([('/', BlogListPage),
                                      ('/entry', BlogEntryPage),
                                      ('/admin', BlogAdminPage),
                                     ],debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

